<template>
    <div>
    <div style="padding:0 10px;">
        <div style="display: flex;justify-content: space-between;align-items: center;">
            <p style="font-size: 16px;">文章分类：</p>
            <el-button type="primary" @click="dialogVisible=true;curopr=0;disabled=false;clearTypeForm();">添加分类</el-button>
        </div>
        <div>
            <el-table :loading="loading" height="365" :border="true" stripe :data="typeData" style="margin-top: 16px;font-size: 14px;"
                :tree-props="{children: 'children'}" row-key="catName" class="type_table"
                :header-cell-style="{ background: '#EBEEF2',borderColor: 'white' }" :row-style="{ height: '60px' }">
                <el-table-column :resizable="false" prop="catName" label="分类名称" min-width="150">
                    <template slot-scope="scope">
                        <span v-if="scope.row.children&&scope.row.children.length>0">{{scope.row.catName}}</span>
                        <span v-else>{{'├&nbsp;&nbsp;&nbsp;'+scope.row.catName}}</span>
                    </template>
                </el-table-column>
                <el-table-column align="center" :resizable="false" header-align="center" label="排序">
                    <template slot-scope="scope">
                        <div class="control" style="font-size: 18px;">
                            <i v-for="item in scope.row.editControl" @click="sort(item,scope)" :class="item"></i>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column :resizable="false" header-align="center" fixed="right" label="操作">
                    <template slot-scope="scope">
                        <div class="control" @click="control(scope.row)">
                            <i class="el-icon-edit-outline" data-control="edit"></i>
                            <i class="el-icon-plus" data-control="plus"></i>
                            <i class="el-icon-delete" data-control="delete"></i>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div style="margin-top: 10px;">总共{{sumCount}}个</div>
    </div>
    <el-dialog append-to-body :title="(curopr===0?'添加':'编辑')+'分类'" :visible.sync="dialogVisible" width="30%">
            <el-form ref="typeRef" :rules="rules" :model="typeForm" label-width="100px">
                <el-form-item prop="categoryName" label="分类名称：">
                    <el-input v-model.trim="typeForm.categoryName" style="width: 70%;"></el-input>
                </el-form-item>
                <el-form-item label="上级分类：">
                    <el-cascader :disabled="disabled" class="cascader" v-model="typeForm.parentId" style="width:70%;" 
                    :options="typeData" change-on-select clearable
                    :props="selectDataProps"></el-cascader>
                </el-form-item>
                <el-form-item label="说明">
                    <el-input type="textarea" v-model.trim="typeForm.memo" maxlength="120" show-word-limit></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="saveCategory">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
import { getArticleCategoryList,saveCategory,deleteCategory,editCategory } from '@/api/api.js'

export default {
    name: 'TypeManager',
    data() {
        return {
            typeData:[
                {
                    catName:'咨询中心',
                    children: [
                        {
                            catName:'企业咨询',
                        },
                        {
                            catName:'企业动态',
                        }
                    ]
                },
                {
                    catName:'产品中心',
                    children: [
                        {
                            catName:'BIM辅助软件',
                            children: [
                                {
                                    catName:'道路模型',
                                },
                                {
                                    catName:'桥梁演示',
                                }
                            ]
                        }
                    ]
                },
                {
                    catName:'分类3',
                },
            ],
            selectDataProps:{ 
                children: 'children', 
                value: 'id', 
                label: 'catName',
                // checkStrictly: true
            },
            searchList:{
                catName:'',
                parentId:''
            },
            loading:false,
            disabled:false,
            dialogVisible:false,
            sumCount:0,
            typeForm:{
                categoryName:'',
                id:'',
                parentId:'',//父级id，根节点-1
                memo:'',//说明
                sortNo:1
            },
            rules: {
                categoryName:[
                    { required: true, message: "分类名称不能为空", trigger: "blur"}
                ]
            },
            curopr:0//0-新增，1-编辑
        }
    },
    async mounted(){
        await this.getArticleCategoryList();
    },
    methods:{
        // 为每条数据添加允许的排序功能-最外层节点
        async addEdit(typeData){
            this.sumCount = 0;
            for(let i=0;i<typeData.length;i++){
                let now = typeData[i];
                now.treeNode = typeData;
                now.index = i;
                now.editControl=[];
                let nowEdit = now.editControl;
                this.sumCount++;
                if(i===0&&(i+1)<typeData.length){
                    nowEdit.push('el-icon-bottom');
                }else if(i>0){
                    nowEdit.push('el-icon-top');
                    if((i+1)<typeData.length) nowEdit.push('el-icon-bottom');
                }
                if(now.children){
                    this.addChrildEdit(now.children,typeData);
                }
            }
        },

        // 为每条数据添加允许的排序功能-内层节点-递归循环
        async addChrildEdit(typeData,parentTreeNode){
            for(let i=0;i<typeData.length;i++){
                let now = typeData[i];
                now.treeNode = typeData;
                now.parentTreeNode = parentTreeNode;
                now.index = i;
                now.editControl=[];
                let nowChrildEdit = now.editControl;
                this.sumCount++;
                if(i===0&&(i+1)<typeData.length){
                    nowChrildEdit.push('el-icon-bottom');
                }else if(i>0){
                    nowChrildEdit.push('el-icon-top');
                    nowChrildEdit.push('el-icon-right');
                    if((i+1)<typeData.length) nowChrildEdit.push('el-icon-bottom');
                }
                nowChrildEdit.push('el-icon-back');
                if(now.children){
                    this.addChrildEdit(now.children,typeData);
                }
            }
        },

        // 上下交换数组位置
        swapArrVertical(arr, index1, index2) {
            arr[index1] = arr.splice(index2, 1, arr[index1])[0];
            return arr;
        },

        // 排序控制器
        sort(control, scope){
            switch(control){
                case 'el-icon-top':
                    this.sortUp(scope);
                    break;
                case 'el-icon-bottom':
                    this.sortDown(scope);
                    break;
                case 'el-icon-right':
                    this.sortRight(scope);
                    break;
                case 'el-icon-back':
                    this.sortLeft(scope);
                    break;
                default:
                    break;
            }
        },

        // 上移按钮
        sortUp(scope){
            if (scope.row.index === 0) {
                this.$message.error('已经处于列表顶部');
            } else {
                scope.row.treeNode = this.swapArrVertical(scope.row.treeNode, scope.row.index, scope.row.index - 1);
                this.addEdit(this.typeData);
            }
        },

        // 下移按钮
        sortDown(scope){
            if (scope.row.index === scope.row.treeNode.length - 1) {
                this.$message.error('已经处于列表底部');
            } else {
                scope.row.treeNode = this.swapArrVertical(scope.row.treeNode, scope.row.index, scope.row.index + 1);
                this.addEdit(this.typeData);
            }
        },

        // 左移按钮
        sortLeft(scope){
            if(scope.row.parentTreeNode==null||scope.row.parentTreeNode.length===0){
                this.$message.error('已经处于列表最左侧');
            }else{
                let parentTreeNode = scope.row.parentTreeNode;
                let nowTreeNode = scope.row.treeNode;
                // 父节点添加当前节点
                parentTreeNode.push(scope.row.treeNode[scope.row.index]);
                // 删除当前节点
                nowTreeNode.splice(scope.row.index,1);
                this.addEdit(this.typeData);
            }
        },

        // 右移按钮
        sortRight(scope){
            if(scope.row.index==0){
                this.$message.error('已经处于列表最右侧');
            }else{
                // 同级树
                let nowTreeNode = scope.row.treeNode;
                // 当前节点下标
                let index = scope.row.index;
                // 若上一行数据无子节点，先初始化
                if(nowTreeNode[index-1].children==null) nowTreeNode[index-1].children = [];
                // 子节点添加当前节点
                nowTreeNode[index-1].children.push(nowTreeNode[index]);
                // 同级树删除当前节点
                nowTreeNode.splice(scope.row.index,1);
                this.addEdit(this.typeData);
            }
        },

        // 获取文章类型列表
        async getArticleCategoryList(){
            try{
                this.loading = true;
                const list = await getArticleCategoryList(this.searchList);
                if(list.data.code == 200){
                    this.typeData = list.data.result;
                    await this.addEdit(this.typeData);
                }else{
                    this.$message({message: '文章分类列表获取失败！',type: 'error'});
                }
            }catch(e){
                this.$message({message: '处理失败！',type: 'error'});
                console.log(e)  
            }finally{
                this.loading = false;
            }
        },

        // 添加编辑文章分类
        async saveCategory(){
            try{
                this.$refs.typeRef.validate(async (valid) => {
                    if (valid) {
                        let list = null;
                        if(this.curopr===0){
                            if(this.typeForm.parentId==null||this.typeForm.parentId=='')this.typeForm.parentId=-1;
                            else if(this.typeForm.parentId instanceof Array) this.typeForm.parentId=this.typeForm.parentId[this.typeForm.parentId.length-1];
                            list = await saveCategory(this.typeForm);
                        }else{ 
                            list = await editCategory(this.typeForm);
                        }
                        if(list.data.code == 200){
                            this.$message({message: `分类${this.curopr===0?'添加':'编辑'}成功！`,type: 'success'});
                            this.getArticleCategoryList();
                            this.dialogVisible = false;
                            // this.updataCategory();
                        }else{
                            this.$message({message: `分类${this.curopr===0?'添加':'编辑'}失败！`,type: 'error'});
                        }
                    }
                })
            }catch(e){
                this.$message({message: '处理失败！',type: 'error'});
                console.log(e)  
            }
        },

        updataCategory(){
            this.$emit('updataCategory');
        },

        clearTypeForm(){
            this.typeForm = {
                categoryName:'',
                id:'',
                parentId:'',//父级id，根节点-1
                memo:'',//说明
            }
        },

        // 操作
        control(row){
            switch(event.target.dataset.control){
                case 'edit':
                    this.clearTypeForm();
                    this.dialogVisible = true;
                    this.typeForm = {
                        categoryName: row.catName,
                        id: row.id,
                        parentId: row.parentId,//父级id，根节点-1
                        memo: row.memo,//说明
                    };
                    this.curopr = 1;
                    this.disabled=true;
                    break;
                case 'plus':
                    this.clearTypeForm();
                    this.curopr = 0;
                    this.dialogVisible = true;
                    this.typeForm.parentId = row.id;
                    this.disabled=false;
                    break;
                case 'delete':
                    this.deleteCategory(row.id);
                    break;
            }
        },

        // 删除文章分类
        async deleteCategory(id){
            try{
                this.$confirm(`是否删除该文章分类?`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(async() => {
                    const result = await deleteCategory(id);
                    if(result.data.code == 200){
                        await this.getArticleCategoryList();
                        this.$message({message:result.data.result,type:'success'});
                    }else{
                        this.$message({message:result.data.result,type:'error'});
                    }
                }).catch(() => {})
            }catch(e){
                this.$message({message: '处理失败！',type: 'error'});
                console.log(e)  
            }
        }
    }
}
</script>

<style scoped>
.control{
    display: flex;
    align-items: center;
    font-size: 25px;
    justify-content: space-around;
}
.control i{
    cursor: pointer;
}
.control i:hover{
    color: rgb(126, 114, 242);
}
.control i:active{
    color: rgba(127, 114, 242, 0.74);
}
.cascader /deep/ .el-radio__input.is-checked .el-radio__inner{
    border-color: #456ddc !important;
    background: #456ddc !important;
}
</style>